package com.gzc.just.play.last.war.allinone.orchestration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 服务器健康检查器
 * 确保端口完全监听后再建立TCP连接
 */
@Component
public class ServerHealthChecker {
    
    private static final Logger logger = LoggerFactory.getLogger(ServerHealthChecker.class);
    
    @Autowired
    private ServerStateManager stateManager;
    
    @Autowired
    private ServerDependencyGraph dependencyGraph;
    
    private final ExecutorService executorService = Executors.newCachedThreadPool();
    private final Map<ServerType, Long> lastHealthCheckTime = new ConcurrentHashMap<>();
    private boolean isRunning = false;
    
    /**
     * 健康检查结果
     */
    public static class HealthCheckResult {
        private final boolean healthy;
        private final String message;
        private final long responseTime;
        
        public HealthCheckResult(boolean healthy, String message, long responseTime) {
            this.healthy = healthy;
            this.message = message;
            this.responseTime = responseTime;
        }
        
        public boolean isHealthy() {
            return healthy;
        }
        
        public String getMessage() {
            return message;
        }
        
        public long getResponseTime() {
            return responseTime;
        }
    }
    
    /**
     * 启动健康检查器
     */
    public void start() {
        logger.info("Starting server health checker...");
        isRunning = true;
        
        // 初始化最后检查时间
        for (ServerType serverType : ServerType.values()) {
            lastHealthCheckTime.put(serverType, 0L);
        }
        
        logger.info("Server health checker started");
    }
    
    /**
     * 停止健康检查器
     */
    public void stop() {
        logger.info("Stopping server health checker...");
        isRunning = false;
        executorService.shutdown();
        logger.info("Server health checker stopped");
    }
    
    /**
     * 定期健康检查
     * 每5秒执行一次
     */
    @Scheduled(fixedRate = 5000)
    public void performHealthCheck() {
        if (!isRunning) {
            return;
        }
        
        Map<String, ServerState> serverStates = stateManager.getAllServerStates();
        
        for (Map.Entry<String, ServerState> entry : serverStates.entrySet()) {
            String serverName = entry.getKey();
            ServerState state = entry.getValue();
            ServerType serverType = ServerType.valueOf(serverName.toUpperCase() + "_SERVER");
            
            // 只对正在运行的服务器进行健康检查
            if (state == ServerState.RUNNING || state == ServerState.LISTENING || state == ServerState.READY) {
                checkServerHealth(serverType);
            }
        }
    }
    
    /**
     * 检查服务器健康状态
     * @param serverType 服务器类型
     */
    public void checkServerHealth(ServerType serverType) {
        lastHealthCheckTime.put(serverType, System.currentTimeMillis());
        
        CompletableFuture<HealthCheckResult> future = CompletableFuture.supplyAsync(() -> {
            return checkTcpConnection(serverType);
        }, executorService);
        
        future.whenComplete((result, throwable) -> {
            if (throwable != null) {
                logger.error("Health check failed for {}", serverType.getName(), throwable);
                stateManager.updateServerState(serverType, ServerState.UNHEALTHY);
            } else {
                if (result.isHealthy()) {
                    // 如果之前是不健康状态，现在恢复为运行状态
                    if (stateManager.getServerState(serverType) == ServerState.UNHEALTHY) {
                        stateManager.updateServerState(serverType, ServerState.RUNNING);
                    }
                } else {
                    stateManager.updateServerState(serverType, ServerState.UNHEALTHY);
                }
            }
        });
    }
    
    /**
     * 检查TCP连接
     * @param serverType 服务器类型
     * @return 健康检查结果
     */
    private HealthCheckResult checkTcpConnection(ServerType serverType) {
        String host = "127.0.0.1";
        int port = serverType.getPort();
        long startTime = System.currentTimeMillis();
        
        try (Socket socket = new Socket()) {
            socket.connect(new InetSocketAddress(host, port), 3000); // 3秒超时
            long responseTime = System.currentTimeMillis() - startTime;
            
            logger.debug("Health check for {} successful, response time: {}ms", 
                       serverType.getName(), responseTime);
            
            return new HealthCheckResult(true, 
                                       "TCP connection successful", 
                                       responseTime);
        } catch (IOException e) {
            long responseTime = System.currentTimeMillis() - startTime;
            
            logger.debug("Health check for {} failed, response time: {}ms, error: {}", 
                        serverType.getName(), responseTime, e.getMessage());
            
            return new HealthCheckResult(false, 
                                       "TCP connection failed: " + e.getMessage(), 
                                       responseTime);
        }
    }
    
    /**
     * 异步检查服务器端口是否可连接
     * @param serverType 服务器类型
     * @return CompletableFuture<HealthCheckResult>
     */
    public CompletableFuture<HealthCheckResult> checkPortReachability(ServerType serverType) {
        return CompletableFuture.supplyAsync(() -> checkTcpConnection(serverType), executorService);
    }
    
    /**
     * 检查服务器是否准备就绪（端口已监听）
     * @param serverType 服务器类型
     * @param timeout 超时时间（毫秒）
     * @return 是否准备就绪
     */
    public boolean waitForServerReady(ServerType serverType, long timeout) {
        long startTime = System.currentTimeMillis();
        long endTime = startTime + timeout;
        
        while (System.currentTimeMillis() < endTime) {
            try {
                HealthCheckResult result = checkTcpConnection(serverType);
                if (result.isHealthy()) {
                    return true;
                }
                
                // 等待1秒后再检查
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
        
        return false;
    }
    
    /**
     * 检查服务器依赖是否都准备就绪
     * @param serverType 服务器类型
     * @return 是否准备就绪
     */
    public boolean areDependenciesReady(ServerType serverType) {
        Map<String, ServerState> serverStates = stateManager.getAllServerStates();
        
        for (ServerType dependency : dependencyGraph.getDependencies(serverType)) {
            ServerState state = serverStates.get(dependency.getName());
            if (state == null || 
                !(state == ServerState.READY || state == ServerState.CONNECTED || state == ServerState.RUNNING)) {
                logger.debug("Dependency {} not ready for {}, current state: {}", 
                           dependency.getName(), serverType.getName(), state);
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * 获取最后健康检查时间
     * @param serverType 服务器类型
     * @return 最后检查时间
     */
    public long getLastHealthCheckTime(ServerType serverType) {
        return lastHealthCheckTime.getOrDefault(serverType, 0L);
    }
    
    /**
     * 检查健康检查器是否正在运行
     * @return 是否正在运行
     */
    public boolean isRunning() {
        return isRunning;
    }
}